// Copyright (c) 2007 Robin Boerdijk. All rights reserved.
//
// This software is licensed under the terms of the Microsoft Reciprocal License as described 
// in the file LICENSE.txt, which you should have received as part of this distribution. The 
// license terms are also available at http://www.opensource.org/licenses/ms-rl.html.

#include "wtkpc.h"

#include "wtk/VerticalBox.h"
#include "wtk/HorizontalBox.h"
#include "wtk/ControlBox.h"

namespace wtk
{
	VerticalBox::VerticalBox(Count initialCapacity)
		: ContainerBox(initialCapacity)
	{
	}

	HorizontalBox *VerticalBox::AddHorizontalBox(Count initialCapacity)
	{
		return Add(new HorizontalBox(initialCapacity));
	}

	SIZE VerticalBox::CalculateMinimumContentSize()
	{
		SIZE size(Zero<SIZE>());
		for (Count i = 0, n = m_boxes.size(); i < n; i++) {
			SIZE boxSize(m_boxes[i]->GetMinimumSize());
			if (boxSize.cx > size.cx) {
				size.cx = boxSize.cx;
			}
			size.cy += boxSize.cy;
		}
		return size;
	}

	long VerticalBox::CalculateHorizontalElasticity()
	{
		long smallestElasticity = 0;
		for (Count i = 0, n = m_boxes.size(); i < n; i++) {
			long elasticity = m_boxes[i]->GetHorizontalElasticity();
			if (elasticity == 0) {
				return 0; // no need to continue
			} else if ((i == 0) || (elasticity < smallestElasticity)) {
				smallestElasticity = elasticity;
			}
		}
		return smallestElasticity;
	}

	long VerticalBox::CalculateVerticalElasticity()
	{
		long totalElasticity = 0;
		for (Count i = 0, n = m_boxes.size(); i < n; i++) {
			totalElasticity += m_boxes[i]->GetVerticalElasticity();
		}
		return totalElasticity;
	}

	void VerticalBox::LayoutContent(const POINT &position, const SIZE &size)
	{
		long stretch = size.cy - GetMinimumSize().cy;
		long totalElasticity = GetVerticalElasticity();
		POINT boxPosition(position);
		for (Count i = 0, n = m_boxes.size(); i < n; i++) {
			Box *box = m_boxes[i];
			SIZE boxSize(Construct<SIZE>(size.cx, box->GetMinimumSize().cy));
			if ((stretch > 0) && (totalElasticity > 0)) {
				long elasticity = box->GetVerticalElasticity();
				if (elasticity > 0) {
					boxSize.cy += (stretch * elasticity) / totalElasticity;
				}
			}
			box->Layout(boxSize, boxPosition);
			boxPosition.y += boxSize.cy;
		}
	}
}
